<template>

  <!--
    例:
    <a-table :loading="loading" ref="aFrom" :tableConfig="tableConfig" v-model="tableData"></a-table>

     loading: 加载中的遮罩层

     selection: 是否多选
     selectKey: 如果配置了这个参数，@selectionChange事件传入的第二个参数就是这key数组
     @selectionChange(selectData,selectKeys):多选触发的事件，返回选中对象

     treeKey: 树形绑定id
     treeProps: 树形配置	{ hasChildren: 'hasChildren', children: 'children' }
     expand: 树形配置，默认展开所有行

     fixed: left左边固定 right右边固定
   -->
  <el-table
    ref="table"
    v-loading="loading"
    :cell-style="{ textAlign: 'left' }"
    :header-cell-style="{ textAlign: 'left' }"
    :data="tableData"
    :default-expand-all="expand"
    :row-key="treeKey"
    :tree-props="treeProps"
    highlight-current-row
    stripe
    style="width: 100%"
    @selection-change="selectionChange"
  >

    <el-table-column v-if="selection === true" :width="50" type="selection" />

    <el-table-column
      v-for="(item,index) in tableConfig"
      v-if="booleanFun(item['if']) && isShowHandle(item.handle)"
      v-show="booleanFun(item['show'])"
      :key="index"
      :align="item.align || 'center'"
      :fixed="item.fixed"
      :label="item.label || '操作'"
      :prop="item.prop"
      :width="item.width"
    >

      <template slot-scope="scope">
        <!--
            插槽
              slot:自定义插槽名称
              label:表头名称
              width:宽度
            使用:<template v-slot:自定义插槽名称='scope'>
            scope值:{row:此记录值，index:所在行数}
        -->
        <slot v-if="item.slot" :index="scope.$index" :name="item.slot" :row="scope.row" />

        <!--
            格式化
              prop:绑定值名称
              label:表头名称
              width:宽度
              formatter(prop,index,row)
                返回值为显示内容
                prop:prop参数绑定的值
                index:索引下标
                row:此行所有数据
        -->
        <span v-else-if="item.formatter">
          <div v-if="item.overflow">
            <el-tooltip class="item" effect="dark" placement="top-start">
              <div v-html="item.formatter(scope.row[item.prop], scope.$index, scope.row)" slot="content"/>
              <div class="oneLine" v-html="item.formatter(scope.row[item.prop], scope.$index, scope.row)"/>
            </el-tooltip>
          </div>
          <div v-else class="oneLine" v-html="item.formatter(scope.row[item.prop], scope.$index, scope.row)"/>
        </span>

        <!--
            字典
              prop:绑定值名称
              label:表头名称
              width:宽度
              dict:字典名称
        -->
        <a-dict v-else-if="item.dict" :options="dictMap[item.dict]" :value="scope.row[item.prop]"/>

        <!--
            日期
              type:'dataFormat'
              prop:绑定值名称
              label:表头名称
              width:宽度
              format:日期格式 (默认格式: {y}-{m}-{d} {h}:{i}:{s} )
        -->
        <span v-else-if="item.type === 'dataFormat'">
          {{ formatTime(scope.row, item) }}
        </span>

        <!--
          操作按钮方法
            handle{
              template: 模板 add、update、delete
              icon: 图标
              text: 显示文字
              handle(): 点击事件(方法)
              hasPer: 权限标识(数组)
            }
        -->
        <span v-else-if="item.handle!==undefined">
          <el-button
            v-for="i in item.handle"
            v-if="i.if === undefined ? true: itemFun(scope, i.if)"
            v-has-permi="i.hasPer"
            :icon="getIcon(i)"
            size="mini"
            type="text"
            @click="() => itemFun(scope, i.handle)"
          >{{ getText(i) }}
          </el-button>
        </span>

        <!--    默认    -->
        <span v-else>
          <div v-if="item.overflow">
            <el-tooltip class="item" effect="dark" placement="top">
              <div v-html="scope.row[item.prop]" slot="content"/>
              <div class="oneLine" v-html="scope.row[item.prop]"/>
            </el-tooltip>
          </div>
          <div v-else class="oneLine" v-html="scope.row[item.prop]"/>
        </span>

      </template>

    </el-table-column>
  </el-table>
</template>

<script>
import store from '@/store'
import aDict from './aDict.vue'

export default {
  name: 'ATable',
  components: {aDict},
  props: {
    tableConfig: {
      type: Array,
      required: true
    },
    value: {
      type: Array,
      required: true
    },
    selection: {
      type: Boolean
    },
    loading: {
      type: Boolean
    },
    treeKey: {
      type: String
    },
    treeProps: {
      type: Object
    },
    expand: {
      type: Boolean
    },
    selectKey: {
      type: String
    }
  },
  data() {
    return {
      tableData: this.value,
      dictMap: {}
    }
  },
  watch: {
    tableData: {
      handler() {
      },
      deep: true,
      immediate: true
    },
    value: {
      handler() {
        this.tableData = this.value
      },
      deep: true,
      immediate: true
    }
  },
  created() {
    this.init()
  },
  methods: {
    // 初始化
    async init() {
      for (let i = 0; i < this.tableConfig.length; i++) {
        const dictKet = this.tableConfig[i].dict
        if (dictKet) {
          this.dictMap[dictKet] = (await this.getDicts(dictKet)).data
          this.dictMap = JSON.parse(JSON.stringify(this.dictMap))
        }
      }
    },
    // 促发item选择回调方法
    selectionChange(val) {
      let valueList = []
      if (this.selectKey !== undefined) {
        valueList = val.map(item => {
          return item[this.selectKey]
        })
      }
      this.$emit('selectionChange', val, valueList)
    },
    // 赋值时间格式
    formatTime(row, item) {
      return this.parseTime(row[item.prop], item.format)
    },
    // item执行方法
    itemFun(event, fun) {
      if (!fun) return
      return fun(event.row, event.$index)
    },
    // 获取boolean值
    booleanFun(value, boolean = true) {
      if (value === undefined || value === null) {
        return boolean
      }
      const type = typeof (value)
      if (type === 'function') {
        return this.booleanFun(value())
      }
      if (type === 'boolean') {
        return value
      }
      console.error(`booleanFun函数不生效，最终解析出应为boolean类型，当前解析出为：${type} 类型`)
    },
    // 是否展示操作列
    isShowHandle(handle) {
      if (handle === undefined) {
        return true
      }
      let totalHasPer = []
      for (let i = 0; i < handle.length; i++) {
        const item = handle[i].hasPer
        if (item === undefined || item === null || item.length === 0) {
          return true
        }
        totalHasPer = totalHasPer.concat(item)
      }
      const all_permission = '*'
      const permissions = store.getters && store.getters.permissions
      return permissions.some(permission => {
        return all_permission === permission || totalHasPer.includes(permission)
      })
    },
    // 获取操作按钮显示icon
    getIcon(data) {
      if (data.template) {
        switch (data.template) {
          case 'add':
            return 'el-icon-plus'
          case 'update':
            return 'el-icon-edit'
          case 'delete':
            return 'el-icon-delete'
          case 'details':
            return 'el-icon-document'
        }
      } else {
        return data.icon
      }
    },
    // 获取操作按钮显示文本
    getText(data) {
      if (data.template) {
        switch (data.template) {
          case 'add':
            return '新增'
          case 'update':
            return '编辑'
          case 'delete':
            return '删除'
          case 'details':
            return '查看'
        }
      } else {
        return data.text
      }
    }

  }
}
</script>

<style scoped>
.oneLine {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>
